package cn.cool.netty.nio.selector;


import lombok.extern.java.Log;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;

@Log
public class Server {
    public static void main(String[] args) throws IOException {
        // 使用 nio 来理解阻塞模式
        // 1. 创建服务器
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false); // 改成非阻塞模式,即 accept()非阻塞
        // 2. 绑定监听端口
        ssc.bind(new InetSocketAddress(8080));
        // 连接集合
        List<SocketChannel> channels = new LinkedList<>();
        ByteBuffer buffer = ByteBuffer.allocate(16);
        // 3. 开启循环监听客户端请求（结果三次握手）
        while (true) {
            // 4. accept() 建立和客户端之间的连接，SocketChannel就是服务端和客户端之间的连接通道
            SocketChannel socketChannel = ssc.accept(); // 非阻塞，线程还会继续运行，如果没有连接建立，sc是null
            if (socketChannel != null) {
                log.info("connected..." + socketChannel);
                socketChannel.configureBlocking(false); // socketChannel设置为非阻塞，read()没有数据时也不会阻塞
                channels.add(socketChannel);
            }

            // 5. 接收客户端发送的数据
            for (SocketChannel channel : channels) {
//                log.info("before reading..." + socketChannel);
                int read = channel.read(buffer);// 非阻塞，线程会继续运行。可以用返回值判断是否有内容
                if (read == 0) continue;

                buffer.flip();
                log.info("read content : "+ Charset.defaultCharset().decode(buffer).toString());
                buffer.clear();
            }
        }
    }
}
